package com.yserp.project.erp.order.saleorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yserp.common.exception.BusinessException;
import com.yserp.common.utils.StringUtils;
import com.yserp.common.utils.bean.BeanUtils;
import com.yserp.common.utils.mybatis.MybatisPlusUtil;
import com.yserp.common.utils.text.Convert;
import com.yserp.project.erp.bill.receivemoney.domain.ReceiveMoneyItem;
import com.yserp.project.erp.common.enums.CheckStatusEnums;
import com.yserp.project.erp.common.enums.OrderEnums;
import com.yserp.project.erp.common.enums.ReceiveMoneyStatusEnums;
import com.yserp.project.erp.order.saleorder.domain.ErpSaleOrder;
import com.yserp.project.erp.order.saleorder.domain.ErpSaleOrderDto;
import com.yserp.project.erp.order.saleorder.domain.ErpSaleOrderItem;
import com.yserp.project.erp.order.saleorder.domain.ErpSaleOrderVo;
import com.yserp.project.erp.order.saleorder.mapper.ErpSaleOrderMapper;
import com.yserp.project.erp.order.saleorder.service.IErpSaleOrderItemService;
import com.yserp.project.erp.order.saleorder.service.IErpSaleOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 销售订单Service业务层处理
 *
 * @author yserp
 * @date 2022-07-07
 */
@Service
public class ErpSaleOrderServiceImpl extends ServiceImpl<ErpSaleOrderMapper, ErpSaleOrder> implements IErpSaleOrderService {
    @Resource
    private ErpSaleOrderMapper erpSaleOrderMapper;
    @Autowired
    private IErpSaleOrderItemService erpSaleOrderItemService;

    /**
     * 查询销售订单
     *
     * @param id 销售订单主键
     * @return 销售订单
     */
    @Override
    public ErpSaleOrderVo selectErpSaleOrderById(Long id) {
        return ErpSaleOrderVo.builder()
                .erpSaleOrder(erpSaleOrderMapper.selectById(id))
                .items(erpSaleOrderItemService.selectErpSaleOrderItemByMainId(id))
                .build();
    }

    /**
     * 查询销售订单列表
     *
     * @param erpSaleOrder 销售订单
     * @return 销售订单
     */
    @Override
    public List<ErpSaleOrder> selectErpSaleOrderList(ErpSaleOrder erpSaleOrder) {
        QueryWrapper<ErpSaleOrder> queryWrapper = new QueryWrapper<>();
        MybatisPlusUtil.notNullField(erpSaleOrder,queryWrapper);
        return erpSaleOrderMapper.selectList(queryWrapper);
    }

    /**
     * 新增销售订单
     *
     * @param erpSaleOrderDto 销售订单
     * @return 结果
     */
    @Override
    public int insertErpSaleOrder(ErpSaleOrderDto erpSaleOrderDto) {
        List<ErpSaleOrderItem> items = erpSaleOrderDto.getItems();
        if (CollectionUtils.isEmpty(items)) {
            throw new BusinessException("子表不能为空");
        }
        //验证单号是否存在
        String orderNo = erpSaleOrderDto.getOrderCode();
        if (StringUtils.isBlank(orderNo)) {
            throw new BusinessException("单号不存在");
        }
        ErpSaleOrder saleOrder = new ErpSaleOrder();
        saleOrder.setOrderCode(orderNo);
        Integer count = erpSaleOrderMapper.selectCount(new QueryWrapper<ErpSaleOrder>().eq("order_code", orderNo));
        if(count>0){
            //处理单号，并重新插入缓存
            Integer number = erpSaleOrderMapper.selectCount(new QueryWrapper<ErpSaleOrder>().like("order_code", orderNo.substring(0,orderNo.length()-3)));
            OrderEnums.putCacheOrderNo(orderNo,number);
            throw new BusinessException("单号已存在，请重新下单");
        }else{
            OrderEnums.putCacheOrderNo(orderNo);
        }

        //插入主表
        ErpSaleOrder erpSaleOrder = new ErpSaleOrder();
        BeanUtils.copyBeanProp(erpSaleOrder, erpSaleOrderDto);
        int i = erpSaleOrderMapper.insert(erpSaleOrder);
        //批量插入子表
        items.stream().forEach(item-> item.setSaleOrderId(erpSaleOrder.getId()));
        erpSaleOrderItemService.saveBatch(items);
        return i;
    }

    /**
     * 修改销售订单
     *
     * @param erpSaleOrderDto 销售订单
     * @return 结果
     */
    @Override
    public int updateErpSaleOrder(ErpSaleOrderDto erpSaleOrderDto) {
        List<ErpSaleOrderItem> items = erpSaleOrderDto.getItems();
        if (CollectionUtils.isEmpty(items)) {
            throw new BusinessException("子表不能为空");
        }
        //插入主表
        ErpSaleOrder saleOrder = new ErpSaleOrder();
        BeanUtils.copyBeanProp(saleOrder, erpSaleOrderDto);
        int i = erpSaleOrderMapper.updateById(saleOrder);
        //获取子表
        List<ErpSaleOrderItem> saleOrderItems = erpSaleOrderItemService.selectErpSaleOrderItemByMainId(saleOrder.getId());
        if (!CollectionUtils.isEmpty(saleOrderItems)) {
            List<Long> oldIds = saleOrderItems.stream().map(ErpSaleOrderItem::getId).collect(Collectors.toList());
            List<Long> newIds = items.stream().map(ErpSaleOrderItem::getId).collect(Collectors.toList());
            oldIds.removeAll(newIds);
            if (!CollectionUtils.isEmpty(oldIds)) {
                erpSaleOrderItemService.removeByIds(oldIds);
            }
        }
        for (ErpSaleOrderItem item : items) {
            if (null == item.getId()) {
                item.setSaleOrderId(saleOrder.getId());
            }
            erpSaleOrderItemService.saveOrUpdate(item);
        }
        return i;
    }

    @Override
    public int updateErpSaleOrderStatus(ErpSaleOrder erpSaleOrder) {
        return erpSaleOrderMapper.updateById(erpSaleOrder);
    }

    /**
     * 批量删除销售订单
     *
     * @param ids 需要删除的销售订单主键
     * @return 结果
     */
    @Override
    public int deleteErpSaleOrderByIds(String ids) {
        int result = 0;
        Long[] mainIds = Convert.toLongArray(ids);
        for (Long id : mainIds ) {
            result =this.deleteErpSaleOrderById(id);
            if(result <= 0){
                break;
            }
        }
        return result;
    }

    /**
     * 删除销售订单信息
     *
     * @param id 销售订单主键
     * @return 结果
     */
    @Override
    public int deleteErpSaleOrderById(Long id) {
        int result = 0;
        //更新主表
        int i=erpSaleOrderMapper.deleteById(id);
        //查询子表信息
        List<ErpSaleOrderItem> items = erpSaleOrderItemService.selectErpSaleOrderItemByMainId(id);
        if(!CollectionUtils.isEmpty(items)) {
            List<Long> itemIds = items.stream().map(ErpSaleOrderItem::getId).collect(Collectors.toList());
            boolean b = erpSaleOrderItemService.removeByIds(itemIds);
            if (i > 0 && b) {
                result = 1;
            }
        }
        return result;
    }

    @Override
    public int auditErpSaleOrderByIds(String ids) {
        Long[] mainIds = Convert.toLongArray(ids);
        ErpSaleOrder erpSaleOrder=null;
        List<ErpSaleOrder> saleOrders =new ArrayList<>();
        for (Long id : mainIds) {
            erpSaleOrder = erpSaleOrderMapper.selectById(id);
            //如果审核通过，无需再次审核
            if(CheckStatusEnums.OK_CHECK.getCode().equals(erpSaleOrder.getOrderStatus())){
                continue;
            }
            erpSaleOrder.setOrderStatus(CheckStatusEnums.OK_CHECK.getCode());
            saleOrders.add(erpSaleOrder);
        }
        if(saleOrders.size()>0) {
            this.updateBatchById(saleOrders);
        }
        return 1;
    }

    @Override
    public List<ReceiveMoneyItem> selectSaleOrderListByCustomerId(Long customerId) {
        List<ReceiveMoneyItem> mapList = new ArrayList<>();
        //查询数据(单独查询)
        QueryWrapper<ErpSaleOrder> queryWrapper = new QueryWrapper<ErpSaleOrder>()
                .eq("customer_id", customerId)
                .eq("order_status", CheckStatusEnums.OK_CHECK.getCode())
                .ne("receive_status", ReceiveMoneyStatusEnums.OK_RECEIVE_MONEY.getCode());
        List<ErpSaleOrder> saleOrderList = erpSaleOrderMapper.selectList(queryWrapper);
        if(!CollectionUtils.isEmpty(saleOrderList)) {
            for (ErpSaleOrder order : saleOrderList) {
                ReceiveMoneyItem item = new ReceiveMoneyItem();
                BigDecimal noReceiveAmount = order.getAmounts().subtract(order.getReceiveAmount());
                item.setSaleId(order.getId());
                item.setSaleCode(order.getOrderCode());
                item.setNoReceiveAmount(noReceiveAmount);
                item.setRemark("");
                mapList.add(item);
            }
        }
        return mapList;
    }


}
